package com.dz.risk.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dz.risk.common.ExcelUtils;
import com.dz.risk.common.GeneralUtils;
import com.dz.risk.common.SysConstant;
import com.dz.risk.common.exception.RRException;
import com.dz.risk.dao.RiskFactorValueDao;
import com.dz.risk.dao.TableDictionaryDao;
import com.dz.risk.pojo.model.FormulaModel;
import com.dz.risk.pojo.ParamsVo;
import com.dz.risk.pojo.QueryParams;
import com.dz.risk.pojo.domain.RiskFactorValueEntity;
import com.dz.risk.pojo.domain.TableDictionaryEntity;
import com.dz.risk.service.CommonService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author baohan
 * @className CommonServiceImpl
 * @description TODO
 * @date 2021/6/28 9:42
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {

    @Autowired
    RiskFactorValueDao riskFactorValueDao;

    @Autowired
    TableDictionaryDao dictionaryDao;


    public static final String SQL_PJ = "\'";

    @Override
    public List<Map<String, Object>> get(String ids, String tableName, String fields) throws RRException {
        List<Map<String, Object>> maps = riskFactorValueDao.getSql(ids, tableName, fields);
        if (null == maps || null == maps.get(SysConstant.ZERO)) {
            log.error("sql 查询 is null" + ids + tableName, fields);
        }
        return maps;
    }

    @Override
    public List<TableDictionaryEntity> getTableAll() throws RRException {
        List<TableDictionaryEntity> list = dictionaryDao.getList();
        return list.stream()
                .filter(o -> String.valueOf(SysConstant.ZERO).equals(o.getParentFileName()))
                // 给每个一级分类加子分类
                .peek(o -> o.setChildren(getChildCategoryList(o, list)))
                // 收集
                .collect(Collectors.toList());
    }

    @Override
    public void updateFormula(ParamsVo paramsVo) throws RRException {
        String tableName = paramsVo.getTableName();
        String fileName = GeneralUtils.camel2under(paramsVo.getFileName());
        //校验字段防止注入问题
        GeneralUtils.isValidSql(tableName);
        GeneralUtils.isValidSql(fileName);
        String id = paramsVo.getId();
        //公式
        String paramsFormula = paramsVo.getParamsFormula();
        List<String> listId = paramsVo.getListId();
        List<String> paramsVoListId = new ArrayList<>();
        for (String sId : listId) {
            //获取参数
            String parms = getParms(sId);
            paramsVoListId.add(parms);
        }
        FormulaModel formulaModel = new FormulaModel();
        formulaModel.setFormulaDetails(paramsFormula);
        formulaModel.setParseFormula(paramsVoListId);
        String calculate = ExcelUtils.calculate(formulaModel);
        formulaModel.setValue(calculate);
        RiskFactorValueEntity valueEntity = new RiskFactorValueEntity();
        valueEntity.setId(id);
        GeneralUtils.setFieldValueByName(valueEntity, fileName, formulaModel);
        riskFactorValueDao.updateByIdTal(SQL_PJ + id + SQL_PJ, tableName, fileName,
                SQL_PJ + JSONObject.toJSONString(formulaModel) + SQL_PJ);
    }

    /**
     * 根据 表名 和 对端 id 取值
     */
    public String getParms(String params) {
        try {
            String[] split = params.split(SysConstant.PASER_ZY);
            //获取表名
            String tableName = split[SysConstant.ZERO];
            //获取行id
            String id = split[SysConstant.ONE];
            //获取字段名
            String fileName = GeneralUtils.camel2under(split[SysConstant.TWO]);
            //表字段验证
            GeneralUtils.isValidSql(tableName);
            List<Map<String, Object>> maps = this.get(SQL_PJ + id + SQL_PJ, tableName, "*");
            Map<String, Object> map = maps.get(SysConstant.ZERO);
            FormulaModel formulaModel = JSONObject.parseObject(map.get(fileName).toString(), FormulaModel.class);
            if (null == formulaModel) {
                log.error("获取单元格value is null 失败！" + params);
            }
            return formulaModel.getValue();
        } catch (Exception e) {
            log.error("获取单元格value 失败！" + params);
            e.printStackTrace();
            throw new RRException("获取单元格value 失败！" + params);
        }
    }

    @Override
    public PageInfo<Map<String, Object>> getTableNameByList(QueryParams queryParams) throws RRException {
        Integer pageNum = queryParams.getPageNum();
        Integer pageSize = queryParams.getPageSize();
        String tableName = queryParams.getTableName();
        int listCount = riskFactorValueDao.getListCount(tableName);
        List<Map<String, Object>> sqlAll = riskFactorValueDao.getSqlAll(tableName, pageNum, pageSize);
        for (Map<String, Object> map : sqlAll) {
            map.forEach((key, value) -> {
                if (value.toString().contains("\"")) {
                    map.put(key, JSON.parseObject(value.toString(), FormulaModel.class));
                }
            });
        }
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>();
        pageInfo.setList(sqlAll);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(pageNum);
        pageInfo.setTotal(listCount);
        return pageInfo;
    }

    /**
     * 树形结构返回
     * @param currMenu
     * @param categories
     * @return
     */
    private List<TableDictionaryEntity> getChildCategoryList(TableDictionaryEntity currMenu, List<TableDictionaryEntity> categories) {
        return categories.stream().filter(o -> o.getParentFileName().equals(currMenu.getTableEnglishName()))
                .peek(o -> o.setChildren(getChildCategoryList(o, categories)))
                .collect(Collectors.toList());
    }
}
